package com.dataaccess.dataaccess.support.udp;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.druid.util.StringUtils;
import com.dataaccess.dataaccess.common.utils.appkit.FirefightingiotKit;
import com.dataaccess.dataaccess.config.rocketmq.UserProducer;
import com.dataaccess.dataaccess.web.service.AutoNetworkAlarmDeviceDataChangedService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

@Component
public class JB_QB_F52_UdpServer {
    @Resource
    UserProducer userProducer;
    @Resource
    AutoNetworkAlarmDeviceDataChangedService autoNetworkAlarmDeviceDataChangedService;

    public void server() throws Exception {
        // 创建服务器端的DatagramSocket，并指定端口
        DatagramSocket datagramSocket = new DatagramSocket(5555);
        System.out.println("*****  启动服务器，等待客户端的连接请求  ******");
        while (true) {
            byte[] data = new byte[100];
            // 创建数据报，用户接受客户端请求的数据
            DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
            // 接收客户端请求的数据（在接收到数据之前一直处于阻塞状态）
            datagramSocket.receive(datagramPacket);
            //原始数据
            String clientData = bytesHex(data);
            JSONObject jsonParam = new JSONObject();
            jsonParam.put("data", clientData);
            jsonParam.put("deviceFlag", "JB_QB_F52");
            String mqFlag = FirefightingiotKit.getStr("mqFlag", "mq");
            if (mqFlag.equals("1")) {
                autoNetworkAlarmDeviceDataChangedService.JB_QB_F52(jsonParam);
            } else if (mqFlag.equals("3")) {
                userProducer.produder(jsonParam.toString());
            }
            //返回数据
            String returnData = clientData.substring(4, 54);
            //流水号+协议号
            String streamNum = clientData.substring(4, 12);
            //设备id
            String deviceID = clientData.substring(24, 36);
            returnData = streamNum + currentTime() + "000000000000" + deviceID + "0000" + "03";
            if (clientData.contains("4040")) {
                returnData = "4040" + returnData + makeChecksum(returnData) + "2323";
            } else {
                returnData = "6464" + returnData + makeChecksum(returnData) + "3535";
            }
            System.out.println("我是服务端，返回的数据为：" + returnData);
            //  *** 给客户端进行相应 ***
            // 定义客户端的地址
            InetAddress inetAddress = datagramPacket.getAddress();
            int port = datagramPacket.getPort();
            byte[] backData = hex2Bytes(returnData);
            // 创建数据包，给客户端响应数据
            DatagramPacket backDatagramPacket = new DatagramPacket(backData, backData.length, inetAddress, port);
            // 给客户端发送数据
            datagramSocket.send(backDatagramPacket);
        }
    }

    /**
     * 16进制单字节累加和校验值（校验和,checksum）
     *
     * @param data
     * @return String
     */
    public static String makeChecksum(String data) {
        if (StringUtils.isEmpty(data)) {
            return "";
        }

        int iTotal = 0;
        int iLen = data.length();
        int iNum = 0;

        while (iNum < iLen) {
            String s = data.substring(iNum, iNum + 2);
            iTotal += Integer.parseInt(s, 16);
            iNum = iNum + 2;
        }

        /**
         * 用256求余最大是255，即16进制的FF
         */
        int iMod = iTotal % 256;
        String sHex = Integer.toHexString(iMod);
        iLen = sHex.length();
        //如果不够校验位的长度，补0,这里用的是两位校验
        if (iLen < 2) {
            sHex = "0" + sHex;
        }
        return sHex;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "40401b0001010000000000000021cf2306200000000000000500990000000001f52323";


    }

    /**
     * @Author YangYu
     * @Description 返回设备的当前时间
     * @Date Created in 13:36 2022/1/10
     * @Param []
     */

    public static String currentTime() {
        String[] waterTime = DateUtil.now().split(" ");
        String date = waterTime[0];
        String[] dateCode = date.split("-");
        String ms = waterTime[1];
        String[] msCode = ms.split(":");
        String currentTime = hex10To16s(msCode[2]) + hex10To16s(msCode[1]) + hex10To16s(msCode[0]) + hex10To16s(dateCode[2]) + hex10To16s(dateCode[1]) + hex10To16s(dateCode[0].substring(2));
        return currentTime;
    }

    private static final char[] HEXES = {
            '0', '1', '2', '3',
            '4', '5', '6', '7',
            '8', '9', 'a', 'b',
            'c', 'd', 'e', 'f'
    };

    public static String bytesHex(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(HEXES[(b >> 4) & 0x0F]);
            hex.append(HEXES[b & 0x0F]);
        }
        return hex.toString();
    }

    public static byte[] hex2Bytes(String hex) {
        if (hex == null || hex.length() == 0) {
            return null;
        }
        char[] hexChar = hex.toCharArray();
        byte[] bytes = new byte[hexChar.length / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt("" + hexChar[i * 2] + hexChar[i * 2 + 1], 16);
        }
        return bytes;
    }

    /**
     * @Author YangYu
     * @Description 十进制字符串转十六进制字符串
     * @Date Created in 10:48 2021/12/15
     * @Param [value]
     */

    public static String hex10To16s(String value) {
        String hex = Integer.toHexString(Integer.parseInt(value));
        if (hex.length() == 1) {
            hex = "0" + hex;
        }
        return hex;
    }

}
